package com.zhangxin.aiInterview.manager.asr;

import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhangxin.aiInterview.common.ErrorCode;
import com.zhangxin.aiInterview.constant.PythonConstant;
import com.zhangxin.aiInterview.exception.BusinessException;
import com.zhangxin.aiInterview.manager.redis.audio_speed.TakeInSpeed;
import com.zhangxin.aiInterview.manager.wsserver.WsManager;
import com.zhangxin.aiInterview.manager.wsserver.enums.WsMessageTypeEnum;
import com.zhangxin.aiInterview.manager.wsserver.model.WsResponseMessage;
import com.zhangxin.aiInterview.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.net.URI;

import static com.zhangxin.aiInterview.constant.PythonConstant.*;

/**
 * ASR ws连接（客户端）
 */
@Slf4j
public class ASRWs {

    /**
     * 初始化连接
     * @param userId 用户id
     * @throws Exception
     */
    public static void init(Long userId){
        websocketWork(python_base_url_ws + "/ASR", userId);
    }

    /**
     * 建立websocket连接
     * @param wsUrl ws服务器地址
     * @param userId 用户id
     */
    public static void websocketWork(String wsUrl, Long userId) {
        try {
            URI uri = new URI(wsUrl);
            WebSocketClient webSocketClient = new WebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake handshake) {
                    System.out.println("ASR WS连接成功");
                }

                @Override
                public void onMessage(String message) {
                    //返回的是json数据，json数据中的中文进行了转义，转义为了unicode编码，需要手动处理
                    String jsonStr = UnicodeUtil.toString(message);
                    System.out.println("收到识别结果：" + jsonStr);

                    //获取ws连接，将数据发送给客户端
                    //解释：匿名内部类中为什么可以使用外部方法的方法参数，是因为匿名内部类在创建的时候就可以捕获到外部方法中的局部变量和方法参数的值所以可以直接使用
                    WebSocketSession webSocketSession = WsManager.getConnection(userId);
                    //构造消息体
                    WsResponseMessage wsResponseMessage = new WsResponseMessage(WsMessageTypeEnum.TEXT.getValue(), jsonStr);
                    TextMessage textMessage = new TextMessage(JSONUtil.toJsonStr(wsResponseMessage));

                    TakeInSpeed takeInSpeed = SpringContextUtil.getBean(TakeInSpeed.class);
                    try {
                        //将语音识别结果发送给客户端
                        webSocketSession.sendMessage(textMessage);

                        // 转换为 JSONObject
                        JSONObject jsonObject = JSON.parseObject(jsonStr);
                        // 获取 code 字段
                        int code = jsonObject.getIntValue("code");
                        // 判断是否为结束消息（code == 2）
                        if (code == 2) {
                            double overallSpeed = jsonObject.getDoubleValue("overallSpeed");
                            String speedUnit = jsonObject.getString("speedUnit");
                            String fullText = jsonObject.getString("fullText");
                            String speed = overallSpeed + speedUnit;
                            System.out.println("识别结束，语速为: " + speed);
                            System.out.println("识别结束，语音识别结果为: " + fullText);
                            // 存入redis中
                            takeInSpeed.takeInSpeed(userId,speed,fullText);
                            //构造消息体
                            WsResponseMessage wsResponseMessage1 = new WsResponseMessage(WsMessageTypeEnum.SPEED.getValue(), speed);
                            TextMessage textMessage1 = new TextMessage(JSONUtil.toJsonStr(wsResponseMessage1));
                            webSocketSession.sendMessage(textMessage1);
                        }
                    } catch (IOException e) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, "ws向客户端发送消息失败");
                    }
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    System.out.println("ASR ws连接关闭: " + reason);
                }

                @Override
                public void onError(Exception ex) {
                    System.err.println("连接异常: " + ex.getMessage());
                }
            };
            //发送建立连接请求
            webSocketClient.connect();
            while (!webSocketClient.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
                Thread.sleep(100);
            }
            //管理ASR ws连接
            ASRWsManager.addOrUpdateConnection(userId, webSocketClient);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}